#include <gtest/gtest.h>

#include "state_machine/v1/state_machine.h"

class StateMachineTestV1 : public ::testing::Test
{
  protected:
    void SetUp() override {}
};

// 测试初始状态
TEST_F(StateMachineTestV1, InitialState)
{
    testing::internal::CaptureStdout();  // 先开始捕获
    StateMachine sm;                     // 构造时会产生初始输出
    std::string output = testing::internal::GetCapturedStdout();

    EXPECT_EQ(sm.getCurrentState(), State::AT_HOME);
    EXPECT_TRUE(output.find("进入在家状态") != std::string::npos);
    EXPECT_TRUE(output.find("躺平追剧") != std::string::npos);
}

// 测试晴天事件转换
TEST_F(StateMachineTestV1, SunnyEventTransition)
{
    testing::internal::CaptureStdout();
    StateMachine sm;  // 捕获初始输出
    std::string initOutput = testing::internal::GetCapturedStdout();
    EXPECT_TRUE(initOutput.find("进入在家状态") != std::string::npos);

    testing::internal::CaptureStdout();
    sm.handleEvent(Event::SUNNY);  // 捕获事件处理输出
    std::string eventOutput = testing::internal::GetCapturedStdout();
    EXPECT_EQ(sm.getCurrentState(), State::OUTSIDE);
    EXPECT_TRUE(eventOutput.find("[事件] 天气转晴") != std::string::npos);
    EXPECT_TRUE(eventOutput.find("离开在家状态") != std::string::npos);
    EXPECT_TRUE(eventOutput.find("进入外出状态") != std::string::npos);
}

// 测试雨天事件转换
TEST_F(StateMachineTestV1, RainEventTransition)
{
    testing::internal::CaptureStdout();
    StateMachine sm;  // 捕获初始输出
    std::string initOutput = testing::internal::GetCapturedStdout();
    EXPECT_TRUE(initOutput.find("进入在家状态") != std::string::npos);

    testing::internal::CaptureStdout();
    sm.handleEvent(Event::SUNNY);  // 第一次状态转换
    std::string sunnyOutput = testing::internal::GetCapturedStdout();
    EXPECT_TRUE(sunnyOutput.find("天气转晴") != std::string::npos);

    testing::internal::CaptureStdout();
    sm.handleEvent(Event::RAINING);  // 第二次状态转换
    std::string rainOutput = testing::internal::GetCapturedStdout();

    EXPECT_EQ(sm.getCurrentState(), State::AT_HOME);

    EXPECT_TRUE(rainOutput.find("开始下雨") != std::string::npos);
    EXPECT_TRUE(rainOutput.find("进入在家状态") != std::string::npos);
}